package ms.jacrim.tropos;

import java.util.ArrayList;
import java.util.List;

import ms.jacrim.tropos.Service.ServiceType;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class Actor extends TroposObject {

	public enum ActorType {
		ROLE, AGENT
	};

	private List<Service> services;
	private ActorType actorType = ActorType.ROLE;

	public Actor(Diagram diagram) {
		super(diagram);
		setType(TroposObject.ACTOR);
		services = new ArrayList<Service>();
	}

	public Actor(Diagram diagram, Actor source) {
		super(diagram, source);
		services = new ArrayList<Service>();
		actorType = source.actorType;
	}

	public Actor(Diagram diagram, Element element) {
		super(diagram, element);
	}

	@Override
	void populate(Element element) {
		super.populate(element);
		if (services == null)
			services = new ArrayList<Service>();

		actorType = ActorType.valueOf(element.getAttribute("actorType"));
		NodeList serviceNodes = element.getElementsByTagName("services");
		for (int i = 0; i < serviceNodes.getLength(); i++)
			services.add(new Service(diagram, (Element) serviceNodes.item(i)));
	}

	public ActorType getActorType() {
		return actorType;
	}

	public void setActorType(ActorType actorType) {
		this.actorType = actorType;
	}

	public List<Service> getServices() {
		return services;
	}

	@Override
	void toString(StringBuilder result, int part, int indent) {
		if (part == 0) {
			writeIndent(result, indent);

			result.append(String.format("<object xmi:type=\"%s\" xmi:id=\"%s\" name=\"%s\" actorType=\"%s\" >\r\n", this.getType(), this
					.getId(), this.getName(), actorType));
			for (Service s : services)
				s.toString(result, 0, indent + 1);

			writeIndent(result, indent);
			result.append("</object>\r\n");
		} else {
			writeIndent(result, indent);
			result.append(String.format("<children xmi:type=\"notation:Node\" xmi:id=\"%s\" type=\"1001\" element=\"%s\">\r\n",
						getNotationID().toString(), getId()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<children xmi:type=\"notation:Node\" xmi:id=\"%s\" type=\"4002\"/>\r\n",
						UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<children xmi:type=\"notation:Node\" xmi:id=\"%s\" type=\"5001\">\r\n",
						UID.generate().toString()));

			for (Service s: services)
				s.toString(result, 1, indent + 2);
			
	        writeIndent(result, indent + 2);
	        result.append(String.format("<styles xmi:type=\"notation:DrawerStyle\" xmi:id=\"%s\"/>\r\n", UID.generate().toString()));
	        writeIndent(result, indent + 2);
	        result.append(String.format("<styles xmi:type=\"notation:SortingStyle\" xmi:id=\"%s\"/>\r\n", UID.generate().toString()));
	        writeIndent(result, indent + 2);
	        result.append(String.format("<styles xmi:type=\"notation:FilteringStyle\" xmi:id=\"%s\"/>\r\n", UID.generate().toString()));
	        
			writeIndent(result, indent + 1);
			result.append("</children>\r\n");
			
			writeIndent(result, indent + 1);
			result.append(String.format("<styles xmi:type=\"notation:FontStyle\" xmi:id=\"%s\" fontName=\"Segoe UI\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<styles xmi:type=\"notation:DescriptionStyle\" xmi:id=\"%s\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<styles xmi:type=\"notation:FillStyle\" xmi:id=\"%s\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<styles xmi:type=\"notation:LineStyle\" xmi:id=\"%s\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<styles xmi:type=\"cust:ActorStyle\" xmi:id=\"%s\" actorWidth=\"90\" actorHeight=\"90\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent + 1);
			result.append(String.format("<layoutConstraint xmi:type=\"notation:Bounds\" xmi:id=\"%s\" width=\"300\" height=\"261\"/>\r\n",
					UID.generate().toString()));
			
			writeIndent(result, indent);
			result.append("</children>\r\n");
		}
	}

	public void addService(Service g) {
		if (services.indexOf(g) < 0)
			services.add(g);
		
	}

	public int indexOfService(String name) {
		for (int i = 0; i < services.size(); i++)
			if (services.get(i).getName().equalsIgnoreCase(name))
				return i;
		return -1;
	}
	
	public Service addService(String name, ServiceType type) {
		int idx = indexOfService(name);
		Service result;
		if (idx < 0) {
			result = new Service(diagram);
			result.setName(name);
			result.setServiceType(type);
			result.setParent(this);
			services.add(result);
		} else result = services.get(idx);
		return result;
	}
}
